package com.fishery.authority.controller;

import com.fishery.authority.service.CaptchaService;
import com.fishery.authority.utils.IpAddressUtil;
import com.fishery.entity.Result;
import com.fishery.entity.StatusCode;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author 白sa能
 * @className
 * @date Created in 10:20 PM 1/19/21
 * @package com.fishery.ucenter.controller
 * @Description
 */
@Api(description = "提供获取图片验证码的接口")
@RestController
@CrossOrigin
@RequestMapping("/captcha")
public class CaptchaController {

    @Value("${captcha.max-visit}")
    private int MAX_VISIT_NUM; // 某个时间段内刷新的最大访问次数

    @Value("${captcha.refresh-time}")
    private int REFRESH_TIME; // 指定刷新的时间段，记录访问次数

    @Value("${captcha.restrict-visit-time}")
    private int RESTRICT_VISIT_TIME; // 禁止访问验证码时间

    @Autowired
    private CaptchaService captchaService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 获取验证码
     */
    @ResponseBody
    @RequestMapping(value = "/getCaptcha", method = RequestMethod.POST)
    public Result captcha(HttpServletRequest request) throws IOException {
        // 获取用户的ip地址
        String ipAdrress = IpAddressUtil.getIpAdrress(request);
        // 通过记录ip访问验证码的访问次数来进行限制，防止用户过分刷验证码
        Object visitNumInRedis = redisTemplate.opsForValue().get("verificationCode_visitNum_ip_" + ipAdrress);
        // 用户第一次获取验证码和超出约定时间内，redis中是没有访问次数的，因此获取值为null
        int visitNum = visitNumInRedis == null ? 1 : (int) visitNumInRedis + 1;
        // 判断是否已经超过了一分钟5次的限制
        if (visitNum > MAX_VISIT_NUM) {
            // 1分钟内超过了5次,禁止访问验证码
            return Result.error("获取验证码过于频繁，请过" + RESTRICT_VISIT_TIME + "分钟后会再尝试");
        } else {
            // 1分钟内未超过了5次，进行累计
            // 获取剩余的时间
            Long expire = redisTemplate.getExpire("verificationCode_visitNum_ip_" + ipAdrress, TimeUnit.SECONDS);
            // 第一次获取的值小于0
            expire = expire < 0 ? REFRESH_TIME : expire;
            // 由于需要设置限制访问时长，因此需要判断此次访问次数是否是最大访问次数
            if (visitNum == MAX_VISIT_NUM) {
                // 此次的访问次数是'MAX_VISIT_NUM',需要把时长设置为'RESTRICT_VISIT_TIME'
                redisTemplate.opsForValue().set("verificationCode_visitNum_ip_" + ipAdrress, visitNum, RESTRICT_VISIT_TIME, TimeUnit.MINUTES);
            } else {
                redisTemplate.opsForValue().set("verificationCode_visitNum_ip_" + ipAdrress, visitNum, expire, TimeUnit.SECONDS);
            }
        }
        return new Result(true, StatusCode.OK, "验证码生成成功", captchaService.createVerificationCode(ipAdrress));
    }
}

